#include "window.h"
#include <unistd.h>

#include <fcntl.h>
namespace client
{
  //1.在构造函数中对窗口设置进行初始化
  Window::Window()
  {
    //设置支持中文格式
    //设置环境变量
    //locale变量都使用系统locale,系统设置的是支持中文
    //此时编译的话就要使用ncursesw库来代替ncurses
    setlocale(LC_ALL,"" ); 
    //打开ncurses模式
    initscr();
    //设置取消光标
    //0:invisible,1;normal.2:very visible
    curs_set(0);
  }

  //2.在析构函数中对窗口设置进行恢复
  //如果忘记设置，程序退出后会导致终端显示异常
  Window::~Window()
  {
    //关闭ncurses模式
    endwin();
  }


  //3.构造聊天界面的标题行窗口
  void Window::Header_Win()
  {
    //因为程序运行时界面大小不一样，ncurses中提供了在运行时获取当前界面的大小
    int h = LINES/6;
    int w = COLS;
    //标题行窗口左上角坐标相对于整个界面的坐标
    int y = 0;
    int x = 0;
    _header_win = newwin(h,w,y,x);  

    //验证是否可以打印出窗口
    //TODO
    std::string str("聊天室");
    Put_String_To_Win(_header_win,h/2,(w - str.size())/2,str);
    //设置边框
    box(_header_win,'|','-');
    //刷新缓冲区
    wrefresh(_header_win);
  }
  //4.构造左部的消息显示窗口
  void Window:: Message_Win() 
  {
    int h = (LINES * 4)/6;
    int w = (COLS * 3)/4;
    int y = LINES/6; 
    int x = 0;

    _message_win = newwin(h,w,y,x);

    int i = 0;
    int size = _msg.size();
    for(i = 0; i < size ;++i)
    {
      Put_String_To_Win(_message_win,i+1,2,_msg[i]);
    }
    box(_message_win,'|','-');
    wrefresh(_message_win);

  }
  //5.构造右部的在线好友列表窗口
  void Window:: Online_List_Win()
  {
    int h = (LINES * 4)/6;
    int w = COLS /4;
    int y = LINES/6; 
    int x = (COLS * 3)/4;

    _online_list_win = newwin(h,w,y,x); 

    int i = 1;
    for(auto item : _online_list)
    {
      Put_String_To_Win(_online_list_win,i++,2,item);
    }

    //以下为测试代码
    FILE * fd = fopen("./log.txt","a");
    fwrite("*************\n",20,1,fd);
    for(auto item : _online_list)
    {
      fwrite(item.c_str(),item.size(),1,fd);
    }
    fwrite("*************\n",20,1,fd);
    fclose(fd);
    //以上为测试代码

    box(_online_list_win,'|','-');
    wrefresh(_online_list_win);
  }
  //6.构造底部输入窗口
  void Window::Input_Win()
  {
    int h = LINES /6;
    int w = COLS;
    int y = (LINES * 5)/6;
    int x = 0;
    _input_win = newwin(h,w,y,x);
    std::string str = "请输入消息 :";
    Put_String_To_Win(_input_win,1,2,str);
    
    box(_input_win,'|','-');
    wrefresh(_input_win);
  }
  //7.往窗口中放置字符串
  void Window::Put_String_To_Win(WINDOW * win,int y,int x,const std:: string & str)
  {
    //往窗口中放置字符串
    mvwaddstr(win,y,x,str.c_str());
  }

  //8.从窗口中获取字符串
  //用于从输入框中获取输入的消息
  void Window::Get_String_From_Win(WINDOW * win,std::string &str)
  {
    char buf[1024 * 10] = {0};
    wgetnstr(win,buf,sizeof(buf) -1);
    str = buf;

    //std::cout<<"从标准输入中读取："<<str<<std::endl;
    
    //此处采用的是拷贝构造，而linux下是默认深拷贝
    //TODO
  }

  //9.添加一条消息双端队列中
  void Window::Add_Msg(const std::string & name,const std::string & words)
  {
    int  max_lines = (LINES * 4)/6 -3;
    if(max_lines < 3)
    {
      //std::cout<<"窗口太小\n";
      //不让其进行插入
      return;
      //exit(1);
    }
    //设置阈值
    if((int)_msg.size() > max_lines)
    {
      _msg.pop_front();
    }
    //将消息尾插到双端队列中
    _msg.push_back("["+name+"]"+":"+words);

  }
  //10.添加一个好友到好友列表中
  void Window::Add_Friend(const std::string & name,const std::string & gender,const std::string & age)
  {
    //当有新的好友上线时，我们应该将好友添加到好友列表中
    _online_list.insert(name+"("+gender+"|"+age+")");
  }

  //11.从好友列表中删除一个好友
  void Window::Del_Friend(const std::string & name,const std::string & gender,const std::string & age)
  {
    //当好友下线时，我们应该将好友从该列表中删除
    _online_list.erase(name+"("+gender+"|"+age+")");
  }

}//end namespace client


#if 0
int main()
{
  client::Window wind;
  wind.Header_Win();
  wind.Input_Win();
  wind.Add_Msg("你好吗？");
  wind.Add_Msg("你好吗？");
  wind.Add_Msg("你好吗？");
  wind.Add_Msg("你好吗？");


  wind.Add_Friend("zdddddd");
  wind.Add_Friend("zdddddd");
  wind.Add_Friend("zdddddd");

  wind.Message_Win();
  wind.Online_List_Win();
  sleep(5);
  return 0;
}

#endif


